﻿// // ******************************************************************
// //       /\ /|       @file       AIBackgroundService.cs
// //       \ V/        @brief      await29
// //       | "")       @author     Await, 285283010@qq.com
// //       /  |
// //      /  \\        @Modified   2025-03-02 10:03
// //    *(__\_\        @Copyright  Copyright (c) , 2025-02-23 10:02 Await
// // ******************************************************************

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using System.Text.Json;
using AutomaticSubtitles.Contracts.Entity;
using AutomaticSubtitles.Contracts.Services;
using AutomaticSubtitles.Service.Application.Cahce.Queries;

namespace AutomaticSubtitles.Service.BackgroundServices;

/// <summary>
/// 自动化ai翻译任务
/// </summary>
public class AIBackgroundService : BackgroundService, ITranslationService, IDisposable
{
    // 添加常量配置
    private const int MAX_RETRY_COUNT = 3;
    private const int RETRY_DELAY_MS = 1000;
    private const int SERVICE_CHECK_INTERVAL_MINUTES = 1;
    private static string? _systemPrompt;
    private readonly SemaphoreSlim _initializationLock = new(1);
    private readonly ILogger<AIBackgroundService> _logger;
    private readonly SemaphoreSlim _semaphore = new(5);
    private readonly IServiceProvider _serviceProvider;
    private IChatCompletionService? _chat;
    private bool _disposed;
    private bool _isRun;

    public AIBackgroundService(
        ILogger<AIBackgroundService> logger,
        IServiceProvider serviceProvider)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
    }

    public override void Dispose()
    {
        if (!_disposed)
        {
            if (_semaphore != null) _semaphore.Dispose();
            if (_initializationLock != null) _initializationLock.Dispose();
            _disposed = true;
        }

        base.Dispose();
    }

    public void ModifyThePromptWord(string commandData)
    {
        if (string.IsNullOrEmpty(commandData))
        {
            _logger.LogWarning("提示词不能为空");
            return;
        }

        _systemPrompt = commandData;
        _logger.LogInformation("提示词已更新");
    }

    public async Task<TranslationModel?> TranslateAsync(TranslationModel model, CancellationToken cancellationToken = default)
    {
        ArgumentNullException.ThrowIfNull(model);

        if (!_isRun || _chat == null)
        {
            _logger.LogWarning("AI服务未初始化或已停止");
            return null;
        }

        if (string.IsNullOrEmpty(model.Value))
        {
            _logger.LogWarning("翻译文本为空");
            return null;
        }

        await _semaphore.WaitAsync(cancellationToken);
        try
        {
            return await TranslateWithRetryAsync(model, cancellationToken);
        }
        finally
        {
            _semaphore.Release();
        }
    }

    public async Task<bool> InitializeTheConfiguration(bool isRun)
    {
        await _initializationLock.WaitAsync();
        try
        {
            if (isRun)
            {
                await InitializeChatService();
                _isRun = true;
                _logger.LogInformation("AI服务初始化成功");
            }
            else
            {
                if (!_isRun)
                {
                    _logger.LogInformation("AI服务已经停止");
                    return true;
                }

                _isRun = false;
                _chat = null;
                _logger.LogInformation("AI服务已停止");
            }

            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "AI服务{Operation}失败", isRun ? "初始化" : "停止");
            return false;
        }
        finally
        {
            _initializationLock.Release();
        }
    }

    private async Task<TranslationModel?> TranslateWithRetryAsync(TranslationModel model, CancellationToken cancellationToken)
    {
        for (var i = 0; i < MAX_RETRY_COUNT; i++)
            try
            {
                var chatHistory = new ChatHistory(_systemPrompt!);
                var prompt = BuildTranslationPrompt(model);
                chatHistory.AddMessage(AuthorRole.User, prompt);
                var response = await _chat!.GetChatMessageContentsAsync(chatHistory, cancellationToken: cancellationToken);
                var result = response[0].Content?.Trim();
                if (string.IsNullOrEmpty(result)) return null;

                _logger.LogDebug("AI原始响应: {Response}", result);

                // 增强的响应清理
                result = CleanResponseText(result);

                _logger.LogDebug("清理后的响应: {Response}", result);

                if (string.IsNullOrEmpty(result) || !result.StartsWith("{") || !result.EndsWith("}"))
                {
                    _logger.LogWarning("AI响应格式无效: {Response}", result);
                    continue;
                }

                var translationResult = ParseTranslationResult(result, model);
                if (translationResult != null) return translationResult;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "第{RetryCount}次翻译尝试失败: {@Model}", i + 1, model);
                if (i == MAX_RETRY_COUNT - 1) return null;
                await Task.Delay(RETRY_DELAY_MS * (i + 1), cancellationToken);
            }

        return null;
    }

    private static string CleanResponseText(string result)
    {
        try
        {
            // 移除所有XML/HTML样式的标签
            result = System.Text.RegularExpressions.Regex.Replace(result, "<[^>]+>", string.Empty);

            // 移除可能的markdown代码块标记
            result = result.Replace("```json", "").Replace("```", "");

            // 查找第一个JSON对象的开始和结束
            var startIndex = result.IndexOf('{');
            var endIndex = result.LastIndexOf('}');

            if (startIndex >= 0 && endIndex > startIndex)
            {
                result = result.Substring(startIndex, endIndex - startIndex + 1);
                // 清理可能的多余空白字符
                result = result.Trim();
            }

            return result;
        }
        catch (Exception)
        {
            return string.Empty;
        }
    }

    private static string BuildTranslationPrompt(TranslationModel model)
    {
        return !string.IsNullOrEmpty(model.LanguageType) && !string.IsNullOrEmpty(model.TranslatedLanguageType)
            ? $"Translate from {model.LanguageType} to {model.TranslatedLanguageType}: {model.Value}"
            : model.Value;
    }

    private static TranslationModel? ParseTranslationResult(string result, TranslationModel originalModel)
    {
        try
        {
            // 移除 deepseek 的深度思考标签
            if (result.Contains("<think>"))
            {
                var startIndex = result.IndexOf("<think>");
                var endIndex = result.IndexOf("</think>") + "</think>".Length;
                if (endIndex > startIndex) result = result.Remove(startIndex, endIndex - startIndex).Trim();
            }

            if (result.Contains('{'))
            {
                result = result[result.IndexOf('{')..];
                if (result.Contains('}')) result = result[..(result.LastIndexOf('}') + 1)];
            }

            var translationResult = JsonSerializer.Deserialize<TranslationModel>(result);
            if (translationResult == null) return null;

            // 保留原始语言类型设置
            if (!string.IsNullOrEmpty(originalModel.LanguageType)) translationResult.LanguageType = originalModel.LanguageType;
            if (!string.IsNullOrEmpty(originalModel.TranslatedLanguageType)) translationResult.TranslatedLanguageType = originalModel.TranslatedLanguageType;

            return translationResult;
        }
        catch (Exception)
        {
            return null;
        }
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            await InitializeChatService(stoppingToken);
            _isRun = true;

            while (!stoppingToken.IsCancellationRequested)
                try
                {
                    await Task.Delay(TimeSpan.FromMinutes(SERVICE_CHECK_INTERVAL_MINUTES), stoppingToken);
                    // 可以在这里添加服务健康检查逻辑
                }
                catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
                {
                    break;
                }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "AI后台服务执行失败");
            _isRun = false;
        }
    }

    private async Task InitializeChatService(CancellationToken cancellationToken = default)
    {
        try
        {
            using var scope = _serviceProvider.CreateScope();
            var eventBus = scope.ServiceProvider.GetRequiredService<IEventBus>();

            // 获取AI配置
            var aiConfig = new GetAiConfigQuery();
            await eventBus.PublishAsync(aiConfig, cancellationToken);

            if (aiConfig.Result == null ||
                string.IsNullOrEmpty(aiConfig.Path) ||
                string.IsNullOrEmpty(aiConfig.Model))
                throw new InvalidOperationException("AI配置无效");

            // 初始化Kernel
#pragma warning disable SKEXP0010
            var kernel = Kernel.CreateBuilder()
                .AddOpenAIChatCompletion(aiConfig.Model, new Uri(aiConfig.Path), aiConfig.Result)
                .Build();
#pragma warning restore SKEXP0010

            _chat = kernel.GetRequiredService<IChatCompletionService>();

            // 获取提示词
            var aiPromptWords = new GetModifyPromptWordQuery();
            await eventBus.PublishAsync(aiPromptWords, cancellationToken);

            _systemPrompt = aiPromptWords.Result ?? GetDefaultPromptWords();
            _logger.LogInformation("AI服务初始化完成");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "初始化AI服务失败");
            throw;
        }
    }

    private static string GetDefaultPromptWords()
    {
        return @"You are a professional translator. Translate the input text and return ONLY in this JSON format:
{
    ""languageType"": ""[source language code]"",
    ""value"": ""[original text]"",
    ""translatedValue"": ""[translated text]"",
    ""translatedLanguageType"": ""[target language code]""
}

EXAMPLES:
Input (en->zh): ""Hello""
{
    ""languageType"": ""en"",
    ""value"": ""Hello"",
    ""translatedValue"": ""你好"",
    ""translatedLanguageType"": ""zh""
}

RULES:
1. NO additional text
2. NO explanations
3. NO tags
4. NO thinking
5. ONLY the JSON object
6. Use ISO 639-1 language codes
7. Detect source language automatically
8. Default target language is English if source is not English, otherwise Chinese";
        // 移动默认提示词到单独的方法
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        try
        {
            _isRun = false;
            _chat = null;
            await base.StopAsync(cancellationToken);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "停止AI服务时发生错误");
            throw;
        }
    }
}